package gbase

import (
	"io"
	"strconv"

	jsoniter "github.com/json-iterator/go"
	"github.com/shopspring/decimal"
)

// Deprecated: Use JsonNum[float64] instead
// 可以处理空字符串的decimal类型
type NullableDecimal struct {
	decimal.Decimal
}

// UnmarshalJSON 自定义JSON解析，处理空字符串情况
func (nd *NullableDecimal) UnmarshalJSON(data []byte) error {
	var str string
	if err := jsoniter.Unmarshal(data, &str); err != nil {
		return err
	}

	// 如果是空字符串，设置为0
	if str == "" {
		nd.Decimal = decimal.Zero
		return nil
	}

	// 解析decimal值
	dec, err := decimal.NewFromString(str)
	if err != nil {
		return err
	}

	nd.Decimal = dec
	return nil
}

// MarshalJSON 自定义JSON序列化
func (nd NullableDecimal) MarshalJSON() ([]byte, error) {
	return jsoniter.Marshal(nd.Decimal.String())
}

// IsZero 判断是否为零值
func (nd NullableDecimal) IsZero() bool {
	return nd.Decimal.IsZero()
}

// String 返回字符串表示
func (nd NullableDecimal) String() string {
	return nd.Decimal.String()
}

// Deprecated: Use JsonNum[float64] instead
// 用于处理json空字符串的
type NullableFloat64 float64

func (nf *NullableFloat64) UnmarshalJSON(data []byte) error {
	// 尝试直接解析为数字
	var num float64
	if err := jsoniter.Unmarshal(data, &num); err == nil {
		*nf = NullableFloat64(num)
		return nil
	}

	// 尝试解析为字符串
	var str string
	if err := jsoniter.Unmarshal(data, &str); err != nil {
		return err
	}

	// 如果是空字符串，设置为0
	if str == "" {
		*nf = 0
		return nil
	}

	// 解析字符串中的float64值
	val, err := strconv.ParseFloat(str, 64)
	if err != nil {
		return err
	}

	*nf = NullableFloat64(val)
	return nil
}

func (nf NullableFloat64) Float64() float64 {
	return float64(nf)
}

func (nf NullableFloat64) String() string {
	return strconv.FormatFloat(float64(nf), 'f', -1, 64)
}

// ProgressReader 带进度的 Reader
type ProgressReader struct {
	reader   io.Reader
	total    int64
	current  int64
	callback func(current, total int64, percent float64)
}

func (pr *ProgressReader) Read(p []byte) (int, error) {
	n, err := pr.reader.Read(p)
	pr.current += int64(n)

	if pr.callback != nil && pr.total > 0 {
		percent := float64(pr.current) / float64(pr.total) * 100
		pr.callback(pr.current, pr.total, percent)
	}

	return n, err
}
